﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
using UnityEditor;

namespace Jelly.Editor.AssetBundle
{
    // 构建assetBundle的配置类
    public class AssetBuilderCfg : FibMatrix.BaseUtils.FibSingletonCfgBase
    {
        [AttributeUsage(AttributeTargets.Class)]
        public class BuildHookAttribute : Attribute
        {

        }
        
        public abstract class CallbackOrderAttribute : Attribute
        {
            protected int m_CallbackOrder;

            public int callbackOrder => this.m_CallbackOrder;
        }
        
        [AttributeUsage(AttributeTargets.Method)]
        public class PreBuildAttribute : CallbackOrderAttribute
        {
            public PreBuildAttribute() => this.m_CallbackOrder = 1;

            public PreBuildAttribute(int callbackOrder) => this.m_CallbackOrder = callbackOrder;
        }
        
        [AttributeUsage(AttributeTargets.Method)]
        public class PostBuildAttribute : CallbackOrderAttribute
        {
            public PostBuildAttribute() => this.m_CallbackOrder = 1;

            public PostBuildAttribute(int callbackOrder) => this.m_CallbackOrder = callbackOrder;
        }
        
        // ------------- 子类必须实现的指定签名的静态单例方法才能显示在ProjectSetting界面
        static AssetBuilderCfg s_Inst;
        public static AssetBuilderCfg Instance
        {
            get
            {   // 注意参数表示是否为运行时资源
                if (s_Inst == null)
                    s_Inst = LoadOrCreate<AssetBuilderCfg>(runtimeAsset: false);
                return s_Inst;
            }
        }
        // --------------------------------------------

        [LabelText("构建AB选项")]
        public BuildAssetBundleOptions buildABOption = BuildAssetBundleOptions.DeterministicAssetBundle |
                        BuildAssetBundleOptions.ChunkBasedCompression |
                        BuildAssetBundleOptions.ForceRebuildAssetBundle |
                        BuildAssetBundleOptions.AssetBundleStripUnityVersion;

        // http://git2.rivergame.net/fibmatrixframework/fibmatrix.unity/issues/5
        [LabelText("尝试兼容同名资源")]
        [Tooltip("具体问题可以看代码注释中的链接。勾选后本bundle中不被其他bundle的资源直接依赖的同名不同路径资源不会引起哈希冲突")] 
        public bool tryFixSameFilenameHashCollision = false;


        // --------------------------------------------------------------------------------
        // shader
        [TitleGroup("Shader相关")]
        [InfoBox("跟SVC同级或子级目录的材质会被打进shader bundle，可用于防止instancing被裁减")]
        [LabelText("Shader变种集合文件路径")]
        [Tooltip("用于描述哪些变种要打到bundle中。路径为编辑器中的，不能用于运行时加载")]
        public string svcPath = "Assets/Shader/WarmupShaderVariants.shadervariants";

        [LabelText("Shader Bundle文件名")]
        public string shaderBundleFilename = "AllShaders.asset";

        [LabelText("shader变种收集只添加完全匹配")]
        [Tooltip("true时材质记录的keywords中的有效部分能完全表示一个有效变种才会记录进svc；false时如果有效部分只是一个子集，会添加最近似的有效变种")]
        public bool shaderVariantCollectorAddExactMatch = false;

        [Space(10)]
        [LabelText("忽略同名sprite检查")]
        [Tooltip("检查时同一SpriteAtlas内有同名Sprite会终止构建；不检查时即使有同名文件也不会有构建错误，只是运行时一个名字不一定对应哪个sprite对象")]
        public bool ignoreDuplicatedSpriteNameCheck = false;

        [Space(10)] 
        [LabelText("使用包内资源列表")]
        [Tooltip("构建时true指定的资源列表不放在包内需要下载；false指定的资源列表才在包内（webgl时会当作预下载资源），其他都要下载。" +
                 "webgl平台会强制用false")]
        public bool useSyncLoadAssetList = false;

        [LabelText("边玩边下资源的配置列表路径")]
        [HideIf("useSyncLoadAssetList")]
        public string webDownloadCfgPath = "Assets/Scripts/Editor/WebDownloadList.txt";
        
        [LabelText("需要同步加载的资源列表")]
        [Tooltip("小游戏时需要把同步加载的资源提前下载好才能运行游戏逻辑，使用修改assetDB文件后缀的路径，比如Assets/xx.tex" + 
                 "可用于在AssetConfig中做key，其依赖也会放到预下载")]
        [ShowIf("useSyncLoadAssetList")]
        public string syncLoadAssetListPath = "Assets/Scripts/Editor/SyncLoadAssets.txt";

        [Space(10)]
        [LabelText("游戏解决方案编译配置")]
        public string gameSolutionAssetPath = "Assets/FM_Mono/Editor/Config/GameProj.asset";

        [Space(10)] 
        [LabelText("最大Patch数")]
        [Tooltip("最大多少个版本的热更文件合成一个patch文件，超过这个数量则以散文集形式下载")]
        public int maxPatchNum = 10;
        
        [LabelText("使用Patch中断版本号")]
        [Tooltip("可以指定一个path版本号，此号及更低的不包含到patch中。如果强更版本是1.0.217 需要设置低一个版本的1.0.216 构建Patch时会从最新版本开始，在该版本停止")]
        public bool usePatchBreakVersion = false;
        
        [LabelText("Patch中断版本号")]
        [ShowIf("usePatchBreakVersion")]
        public string patchBreakVersion = "1.0.216";
        

        // --------------------------------------------------------------------------------
    }

}